package cn.edu.lcu.cs.javaprogramming.clazz;


import cn.edu.lcu.cs.javaprogramming.oop.Student;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;

import java.util.Arrays;
import java.util.Locale;
import java.util.Optional;
import java.util.StringJoiner;

import static org.junit.jupiter.api.Assertions.*;

public class StringDemo {
    String lorem = "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Porro, nemo, incidunt, facere debitis delectus nesciunt temporibus asperiores laborum commodi voluptas iure inventore quidem officia laudantium aperiam dolore officiis quia facilis.";

    @Test
    void lorem() {
        // 统计 lorem 单词的个数
        String[] words = lorem.split("[ ,.]");
        System.out.println("words.length = " + words.length);
        System.out.println("Arrays.toString(words) = " + Arrays.toString(words));
        Object[] compactWords = Arrays.stream(words).filter(w -> !w.isEmpty()).toArray();
        System.out.println("compactWords.length = " + compactWords.length);
        System.out.println("Arrays.toString(compactWords) = " + Arrays.toString(compactWords));
    }

    /**
     * 字符串的相等判断，应该用equals方法。
     */
    @Test
    public void equals() {
        // 字符串是特殊的对象，在堆上分配，不可更改，唯一
        String lisi = "lisi";
        String lisi2 = "lisi";
        String lisi3 = "LisI".toLowerCase();
        // 编译期字符串被保存在常量池
        // 编译期就可确定内容相同的字符串指向相同的字符串
        // 所以这两个串用 == 判断结果相等
        assertTrue(lisi == lisi2);
        assertTrue(lisi.equals(lisi2));

        // 这两个串编译期是不同的，所以两个引用变量指向不同的对象。
        assertFalse(lisi2 == lisi3);
        // 但是这两个串的内容相同
        assertTrue(lisi3.equals(lisi2));
    }

    /**
     * 字符串拆分演示。
     */
    @Test
    public void split() {
        String string = "2021-04-18 22:23:28";
        // 依据正则表达式拆分字符串为字符串数组
        String[] split = string.split("[-: ]");
        System.out.println(Arrays.toString(split));

        String url = "http://ee-c.lcu.edu.cn/";
        String[] split2 = url.split("[:/.]");
        System.out.println(Arrays.toString(split2));
    }

    /**
     * 将下划线分隔的字符串转换为驼峰模式
     *
     * @param underScoreString
     */
    @ParameterizedTest
    @ValueSource(strings = {"map_under_score_to_camel_case"})
    public void mapUnderScoreToCamelCase(String underScoreString) {
        if (underScoreString == null) {
            return;
        }
        String[] splited = underScoreString.split("_");
//		String joined = String.join("", splited);
//		System.out.println(joined);
        Optional<String> reduced = Arrays.stream(splited) //
                .map(s -> {
                    char[] chars = s.toCharArray();
                    if (chars[0] >= 'a' && chars[0] <= 'z') {
                        chars[0] -= 0X20;
                        return String.valueOf(chars);
                    }
                    return s;
                }) //
                .reduce((result, item) -> result + item);
        System.out.println(reduced.get());
    }

    @ParameterizedTest
    @ValueSource(strings = {"hello", "", "Hello", "你好"})
    void toUpperCaseFirstLetter(String src) {
        if (src != null && src.length() >0) {
            char[] chars = src.toCharArray();
            chars[0] = Character.toUpperCase(chars[0]);
            String target = String.valueOf(chars);
            System.out.println("src = " + src);
            System.out.println("target = " + target);
        }
    }

    /**
     * 根据表名及列名数组，创建sql查询语句。
     */
    @Test
    void selectSql() {
        String table = "student";
        String[] columns = {"id", "name", "studentNo"};

        StringJoiner select = new StringJoiner(", ", "select ", " from " + table);
        for (String column : columns) {
            select.add(column);
        }
        assertEquals("select id, name, studentNo from student", select.toString());
    }


    @AfterEach
    void afterEach() {
        System.out.println("---------------------------------------------------------");
    }
}
